/*
 * CacheDirectorio.c
 *
 *  Created on: 01/12/2011
 *      Author: utn_so
 */
#include "CacheDirectorio.h"

//Mutex para administrar el recurso de la cache de directorio
extern pthread_mutex_t mutex_cacheDirectorio;

uint32_t inicializarCacheDirectorio(){

	uint32_t i;
	for(i = 0; i < (TAM_CACHE_DIR - 1); i++){
		vectorAccesosCacheDir[i] = 0;
		cacheDirectorio[i].listaDirectorios = malloc(sizeof(ListaDirectorios));
		cacheDirectorio[i].path = malloc(sizeof(char)*40);
		strcpy(cacheDirectorio[i].path, "void");
	}
//La ultima posicion de la cache es un contador.
	vectorAccesosCacheDir[TAM_CACHE_DIR - 1] = 0;
	return 0;
}

uint32_t agregarCacheDirectorio(const char* path, ListaDirectorios* directoryList){
	pthread_mutex_lock(&mutex_cacheDirectorio);

	uint32_t pos = obtenerPosMenosUsado();

	if(strcmp("void", cacheDirectorio[pos].path) != 0){
		free(cacheDirectorio[pos].listaDirectorios -> directorio);
		free(cacheDirectorio[pos].listaDirectorios -> nombreLargo);
	}

	cacheDirectorio[pos].listaDirectorios -> directorio = directoryList -> directorio;
	cacheDirectorio[pos].listaDirectorios -> nombreLargo = directoryList -> nombreLargo;
	cacheDirectorio[pos].listaDirectorios -> parentCluster = directoryList ->parentCluster;
	cacheDirectorio[pos].listaDirectorios -> posicionEntrada = directoryList ->posicionEntrada;

	strcpy(cacheDirectorio[pos].path, path);
	vectorAccesosCacheDir[pos] = 1;

	if(vectorAccesosCacheDir[TAM_CACHE_DIR -1] < TAM_CACHE_DIR ){
		vectorAccesosCacheDir[TAM_CACHE_DIR -1] = vectorAccesosCacheDir[TAM_CACHE_DIR -1]++;
	}

	pthread_mutex_unlock(&mutex_cacheDirectorio);
	return pos;
}

ListaDirectorios* buscarCacheDirectorio(const char* path){
	pthread_mutex_lock(&mutex_cacheDirectorio);

	uint32_t i;
	for(i = 0; i < (TAM_CACHE_DIR -1); i++){
		if(strcmp(path, cacheDirectorio[i].path) == 0){
			vectorAccesosCacheDir[i] = 1;
			pthread_mutex_unlock(&mutex_cacheDirectorio);
			return cacheDirectorio[i].listaDirectorios;
		}
	}

	pthread_mutex_unlock(&mutex_cacheDirectorio);
	return NULL;
}

uint32_t obtenerPosMenosUsado(){
	uint32_t i;
	uint32_t pos;
	pos = 0;

	if(vectorAccesosCacheDir[TAM_CACHE_DIR -1] >= TAM_CACHE_DIR){
		reinicializarvectorAccesosCacheDir();
	}

	for(i = 0; i < (TAM_CACHE_DIR -1); i++){
		if(vectorAccesosCacheDir[i] == 0){
			return i;
		}
	}
	return pos;
}

uint32_t reinicializarvectorAccesosCacheDir(){
	int i;
	for(i = 0; i < TAM_CACHE_DIR; i++){
		vectorAccesosCacheDir[i] = 0;
	}
	return 0;
}

uint32_t eliminarDatoCacheDirectorio(const char* path){
	pthread_mutex_lock(&mutex_cacheDirectorio);

	uint32_t i;
		for(i = 0; i < (TAM_CACHE_DIR -1); i++){
			if(strcmp(path, cacheDirectorio[i].path) == 0){
				free(cacheDirectorio[i].listaDirectorios -> directorio);
				free(cacheDirectorio[i].listaDirectorios -> nombreLargo);
				strcpy(cacheDirectorio[i].path, "void");
				vectorAccesosCacheDir[i] = 0;
			}
		}

	pthread_mutex_unlock(&mutex_cacheDirectorio);
	return 0;
}

uint32_t renombrarDatoCacheDirectorio(const char* newPath, const char* oldPath, ListaDirectorios* newLd){
	pthread_mutex_lock(&mutex_cacheDirectorio);

	uint32_t i;
			for(i = 0; i < (TAM_CACHE_DIR -1); i++){
				if(strcmp(oldPath, cacheDirectorio[i].path) == 0){
//EN LA BUSQUEDA SE DEVUELVE EL ORIGINAL POR ESO NO ES NECESARIO COPIAR NADA
					strcpy(cacheDirectorio[i].path, newPath);
					vectorAccesosCacheDir[i] = 1;
				}
			}
		pthread_mutex_unlock(&mutex_cacheDirectorio);
		return 0;
}
